package com.fingard.dsp.bank.directbank.bocom15;

import com.allinpay.ets.client.StringUtil;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.bankInterface.IContract;
import com.fingard.dsp.bank.directbank.bocom13.BOCOM13Header;
import com.fingard.dsp.bank.directbank.bocom13.BOCOM13TransCode;
import com.fingard.dsp.bank.reqrespobj.contract.*;
import com.fingard.dsp.bank.reqrespobj.contract.detail.RetAtsContractDetail;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;
import org.apache.commons.lang.StringEscapeUtils;

import java.util.Date;

public class BOCOM15Contract extends BOCOM15Base implements IContract {
    String tmpBusDate = "BusDate";
    String tmpSeqNo = "SeqNo";
    String tmpSignConfirm = "signConfirm";

    @Override
    public RetAtsContract contract(ReqContract p_req) throws Exception {
        RetAtsContract retAts = new RetAtsContract(p_req.reqHeader);
        RetAtsContractDetail tmpRetDetail = new RetAtsContractDetail();
        tmpRetDetail.reqSeqID = p_req.contractDetail.askNumber;
        try {
            XmlTextWriter xmlWriter = new XmlTextWriter();
            BOCOM13Header tmpBankHeader = new BOCOM13Header();
            tmpBankHeader.reqSeqID = p_req.contractDetail.askNumber;
            String corpNo = getBankConfig().getMapValueByKey("corpNoMapping", p_req.contractDetail.recAct);
            if (StringHelper.isNullOrEmpty(corpNo)) {
                tmpRetDetail.respCode = "0";
                tmpRetDetail.respInfo = "未找到账号[" + p_req.contractDetail.recAct + "]保险方ID映射,请检查BOCOM15/config.xml中'corpNoMapping'节点配置";
                tmpRetDetail.signState = ContractState.FAIL;
                retAts.writeRetDetail(tmpRetDetail);
                return retAts;
            }
            tmpBankHeader.corpNo = corpNo;
            XmlTextWriter xmlWriterInner = new XmlTextWriter();
            if ("01".equals(p_req.contractDetail.step)) {

                if ("2".equals(getBankConfig().getValueAsString(tmpSignConfirm))) {
                    tmpBankHeader.transCode = "I00407";
                } else if ("3".equals(getBankConfig().getValueAsString(tmpSignConfirm))) {
                    tmpBankHeader.transCode = "I00401";
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = "请检查节点配置：signConfirm";
                    retAts.writeRetDetail(tmpRetDetail);
                    return retAts;
                }
                writeCommonHeader(xmlWriterInner, tmpBankHeader);
                xmlWriterInner.writeStartElement("Body");
                xmlWriterInner.writeElementString(tmpBusDate, Format.Date8Format.format(new Date()));/* 保险方业务日期 */
                xmlWriterInner.writeElementString(tmpSeqNo, tmpBankHeader.reqSeqID);/* 保险方流水号 */
                xmlWriterInner.writeElementString("ApplyNo", p_req.contractDetail.insuPolicyNum);/* 投保单号 */
                xmlWriterInner.writeElementString("PolNo", p_req.contractDetail.certNum);/* 保单号 */
                xmlWriterInner.writeElementString("Name", p_req.contractDetail.payName);/* 客户姓名 */
                xmlWriterInner.writeElementString("IdType", convertCertTypeToBank(p_req.contractDetail.certType));/* 证件类型 */
                xmlWriterInner.writeElementString("IdNo", p_req.contractDetail.certNum);/* 证件号码 */
                xmlWriterInner.writeElementString("Telephone", p_req.contractDetail.cellPhone);/* 手机号码 */
                String isPrivate = "";
                if (StringHelper.hasAnyChar(p_req.contractDetail.isPrivate)) {
                    if ("1".equals(p_req.contractDetail.isPrivate)) {
                        isPrivate = "P";
                    } else {
                        isPrivate = "E";
                    }
                } else {
                    isPrivate = "P";
                }
                xmlWriterInner.writeElementString("EpFlag", isPrivate);/* 公私标志(E-对公,P-对私) */
                xmlWriterInner.writeElementString("PrdName", "");/* 险种名称 */
                xmlWriterInner.writeElementString("ActNo", p_req.contractDetail.payAct);/* 账号 */
                xmlWriterInner.writeElementString("CurType", "CNY");/* 交易币种 */
                String BusType = getBankConfig().getMapValueByKey("contractBusiCode", p_req.contractDetail.busType);
                if ("I00407".equals(tmpBankHeader.transCode)) {
                    xmlWriterInner.writeElementString("BusType", BusType);/* 交易币种 */
                } else {
                    xmlWriterInner.writeElementString("BusType", "D10");/* 收付种类:D10-首期缴费(2.42收付种类) */
                }
                xmlWriterInner.writeElementString("Ext001", "");
                xmlWriterInner.writeElementString("Ext002", "");
                xmlWriterInner.writeElementString("Ext003", "");
                xmlWriterInner.writeElementString("Ext004", "");
                xmlWriterInner.writeElementString("Ext005", "");
                xmlWriterInner.writeElementString("Ext006", "");
                xmlWriterInner.writeElementString("Ext007", "");
                xmlWriterInner.writeElementString("Ext008", "");
                xmlWriterInner.writeElementString("Ext009", "");
                xmlWriterInner.writeElementString("Ext010", "");
                xmlWriterInner.writeEndDocument();
                txCode = "ECIP000095";
                reqSeqID = p_req.contractDetail.askNumber;
                writeCommonHeader(xmlWriter);
            } else if ("02".equals(p_req.contractDetail.step)) {
                tmpBankHeader.transCode = "I00408";
                writeCommonHeader(xmlWriterInner, tmpBankHeader);
                xmlWriterInner.writeStartElement("Body");
                xmlWriterInner.writeElementString(tmpBusDate, Format.Date8Format.format(new Date()));/* 保险方业务日期 */
                xmlWriterInner.writeElementString(tmpSeqNo, tmpBankHeader.reqSeqID);/* 保险方流水号 */
                xmlWriterInner.writeElementString("OriSeqNo", p_req.contractDetail.askNumber);/* 签约申请的流水号 	*/
                xmlWriterInner.writeElementString("IdentifyCode", p_req.contractDetail.smsCode);/* 签约申请的流水号 	*/
                xmlWriterInner.writeElementString("Ext001", "");
                xmlWriterInner.writeElementString("Ext002", "");
                xmlWriterInner.writeElementString("Ext003", "");
                xmlWriterInner.writeElementString("Ext004", "");
                xmlWriterInner.writeElementString("Ext005", "");
                xmlWriterInner.writeElementString("Ext006", "");
                xmlWriterInner.writeElementString("Ext007", "");
                xmlWriterInner.writeElementString("Ext008", "");
                xmlWriterInner.writeElementString("Ext009", "");
                xmlWriterInner.writeElementString("Ext010", "");
                xmlWriterInner.writeEndDocument();
                txCode = "ECIP000095";
                reqSeqID = p_req.reqHeader.transSeqID;
                writeCommonHeader(xmlWriter);
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = "未能识别的step：" + p_req.contractDetail.step;
                retAts.writeRetDetail(tmpRetDetail);
                return retAts;
            }
            String xml = xmlWriterInner.toXmlString();
            String mac = getBankConfig().getValueAsString("mac");
            WriteBankLogLn("MAC值:" + mac);
            String headLenth = String.format("%8s", mac.length() + xml.length() + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>".length()).replace(" ", "0");
            WriteBankLogLn("报文长:" + headLenth);
            String head = headLenth + mac;
            xmlWriter.writeElementString("Transaction_Head", head);
            xmlWriter.writeElementString("Transaction_Body", StringEscapeUtils.unescapeXml(xml));
            xmlWriter.writeEndDocument();//Transaction_Body
            String[] tmpStrRet = sendToBank(StringEscapeUtils.unescapeXml(xmlWriter.toXmlString()));
            StringBuilder tmpSbMsg = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
            if (tmpBkReader != null) {
                String returnMsg = tmpBkReader.getFirstText("/TX/TX_BODY/ENTITY/Transaction_Body");
                XmlTextReader tmpBkReaders = loadBankRespXmlReader(returnMsg, tmpSbMsg);
                if (tmpBkReaders != null) {
                    tmpRetDetail.respCode = "0";
                    tmpRetDetail.respInfo = tmpBkReaders.getFirstText("/Rsp/Head/ErrMsg");
                    String tmpMsgType = tmpBkReaders.getFirstText("/Rsp/Head/MsgType");
                    String tmpErrCode = tmpBkReaders.getFirstText("/Rsp/Head/ErrCode");
                    String signno = tmpBkReaders.getFirstText("/Rsp/Body/AgreementNo");
                    if ("01".equals(p_req.contractDetail.step)) {
                        if (!"N".equals(tmpMsgType)) {
                            tmpRetDetail.respCode = "-1";
                        }
                        if ("000000".equals(tmpErrCode) && !StringUtil.isEmpty(signno)) {
                            tmpErrCode = "3068";
                            tmpRetDetail.authCode = signno;
                        }
                        tmpRetDetail.signConfirmType = this.getBankConfig().getValueAsString(tmpSignConfirm);
                    } else {
                        String Stats = tmpBkReaders.getFirstText("/Rsp/Body/Stats");
                        String ErrMsg = tmpBkReaders.getFirstText("/Rsp/Body/ErrMsg");
                        if ("1".equals(Stats) || "200077".equals(tmpErrCode)) {
                            // 签约状态: 0-处理中 1-成功 2-失败
                            tmpRetDetail.signState = ContractState.SUCCESS;
                            tmpRetDetail.authCode = signno;
                            tmpRetDetail.newAuthCode = signno;
                        } else if ("2".equals(Stats)) {
                            tmpRetDetail.respInfo = ErrMsg;
                            tmpRetDetail.signState = ContractState.FAIL;
                        } else if ("0".equals(Stats)) {
                            tmpRetDetail.signState = ContractState.SIGNING;
                            tmpRetDetail.respInfo = ErrMsg;
                        } else {
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = ErrMsg;
                        }
                    }
                    tmpRetDetail.unifiedCode = getBankConfig().getMapValueByKey("contractMapping", tmpErrCode);
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = tmpSbMsg.toString();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }
        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    @Override
    public RetAtsContract upContract(ReqContract p_req) throws Exception {
        return null;
    }

    @Override
    public RetAtsContract qryContract(ReqContract p_reqQry) throws Exception {
        RetAtsContract retAts = new RetAtsContract(p_reqQry.reqHeader);
        RetAtsContractDetail tmpRetDetail = new RetAtsContractDetail();
        tmpRetDetail.reqSeqID = p_reqQry.contractDetail.askNumber;
        try {
            XmlTextWriter xmlWriter = new XmlTextWriter();
            txCode = "ECIP000097";
            reqSeqID = getQryTransID();
            writeCommonHeader(xmlWriter);

            BOCOM13Header tmpBankHeader = new BOCOM13Header();
            tmpBankHeader.transCode = BOCOM13TransCode.realTime_QryContract_9108Auth;
            tmpBankHeader.reqSeqID = p_reqQry.contractDetail.askNumber;
            String corpNo = getBankConfig().getMapValueByKey("corpNoMapping", p_reqQry.contractDetail.recAct);
            if (StringHelper.isNullOrEmpty(corpNo)) {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = "未找到账号[" + p_reqQry.contractDetail.recAct + "]保险方ID映射,请检查BOCOM13/config.xml中'corpNoMapping'节点配置";
                retAts.writeRetDetail(tmpRetDetail);
                return retAts;
            }
            tmpBankHeader.corpNo = corpNo;
            XmlTextWriter xmlWriterInner = new XmlTextWriter();
            writeCommonHeader(xmlWriterInner, tmpBankHeader);
            xmlWriterInner.writeStartElement("Body");
            xmlWriterInner.writeElementString(tmpBusDate, Format.Date8Format.format(new Date()));
            xmlWriterInner.writeElementString(tmpSeqNo, tmpBankHeader.reqSeqID);
            xmlWriterInner.writeEndDocument();
            String xml = xmlWriterInner.toXmlString();
            String mac = getBankConfig().getValueAsString("mac");
            WriteBankLogLn("MAC值:" + mac);
            String headLenth = String.format("%8s", mac.length() + xml.length() + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>".length()).replace(" ", "0");
            WriteBankLogLn("报文长:" + headLenth);
            String head = headLenth + mac;
            xmlWriter.writeElementString("Transaction_Head", head);
            xmlWriter.writeElementString("Transaction_Body", StringEscapeUtils.unescapeXml(xml));
            xmlWriter.writeEndDocument();//Transaction_Body
            String[] tmpStrRet = sendToBank(StringEscapeUtils.unescapeXml(xmlWriter.toXmlString()));
            StringBuilder tmpSbMsg = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
            if (tmpBkReader != null) {
                String returnMsg = tmpBkReader.getFirstText("/TX/TX_BODY/ENTITY/Transaction_Body");
                XmlTextReader tmpBkReaders = loadBankRespXmlReader(returnMsg, tmpSbMsg);
                if (tmpBkReaders != null) {
                    tmpRetDetail.respCode = "0";
                    tmpRetDetail.respInfo = tmpBkReaders.getFirstText("/Rsp/Head/ErrMsg");

                    String tmpMsgType = tmpBkReaders.getFirstText("/Rsp/Head/MsgType");
                    String tmpErrCode = tmpBkReaders.getFirstText("/Rsp/Head/ErrCode");
                    if ("N".equals(tmpMsgType) && "000000".equals(tmpErrCode)) {
                        // 签约状态: 0-处理中 1-成功 2-失败 3-超时
                        String signStatus = tmpBkReaders.getFirstText("/Rsp/Body/AgreementStat");
                        if ("1".equals(signStatus)) {
                            tmpRetDetail.signState = ContractState.SUCCESS;

                            String authCode = tmpBkReaders.getFirstText("/Rsp/Body/AgreementNo");/* 代收协议编号 */
                            tmpRetDetail.authCode = authCode;
                            tmpRetDetail.newAuthCode = authCode;
                        } else if ("2".equals(signStatus)) {
                            tmpRetDetail.signState = ContractState.FAIL;
                        } else {
                            tmpRetDetail.signState = ContractState.SIGNING;
                        }
                    } else if ("E".equals(tmpMsgType) && "200069".equals(tmpErrCode)) {
                        tmpRetDetail.respCode = "0";
                        tmpRetDetail.signState = ContractState.UNSIGNED;
                        tmpRetDetail.respInfo = "记录不存在";
                    } else if ("E".equals(tmpMsgType) && "200018".equals(tmpErrCode)) {
                        tmpRetDetail.respCode = "0";
                        tmpRetDetail.signState = ContractState.UNSIGNED;
                        tmpRetDetail.respInfo = "流水号为空";
                    } else {
                        tmpRetDetail.respCode = "-1";
                    }
                    tmpRetDetail.signConfirmType = this.getBankConfig().getValueAsString(tmpSignConfirm);
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpSbMsg.toString();
                }

            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = tmpSbMsg.toString();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }
        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    @Override
    public RetAtsQryBatContract qryBatContract(ReqQryBatContract p_reqQry) throws Exception {
        return null;
    }
}
